<?php

// determine if the database connection configuration is available
// if not, include the connection information
if( !defined("DB_HOST") ) {
    trigger_error("Database configuration is incorrect");
    return;
}

/**
 * Create a class for easily accessing the database and making modifications
 * in a object oriented manner
 */
class Database {

    private $db_host = DB_HOST;
    private $db_user = DB_USER;
    private $db_pass = DB_PASS;
    private $db_name = DB_NAME;
    private $query = NULL;
    private $result = array();
	private $error = NULL;
    private $con = NULL;
    public static $debug = false;

    public function __construct() {
        $this->connect();
    }

    public function connect() {
        global $config;
        
        if ($this->con == NULL && !isset($config)) {
            $this->con = mysqli_connect($this->db_host,  $this->db_user,  $this->db_pass) or 
                die('<h1>Error connecting to database. Please check your settings.</h1>');
            
            mysqli_select_db( $this->con, $this->db_name);
            return true;
            

        } else {
            $this->con = $config;
            return true;
        }
    }
	
	public function getConnection() {
		return $this->con;	
	}

    public function disconnect() {
        if($this->con) {
            if(mysqli_close($this->con)) {
                $this->con = false;
                return true;
            } else {
                return false;
            }
        }
    }

    public function sanitizeInput($theValue, $theType = NULL, $theDefinedValue = "", $theNotDefinedValue = "") {
        if (PHP_VERSION < 6) {
            $theValue = get_magic_quotes_gpc() ? stripslashes($theValue) : $theValue;
        }

        $theValue = function_exists("mysqli_real_escape_string") ? ((isset($this->con) && is_object($this->con)) ? mysqli_real_escape_string($this->con, $theValue) : ((trigger_error("[MySQLConverterToo] Fix the mysql_escape_string() call! This code does not work.", E_USER_ERROR)) ? "" : "")) : ((isset($this->con) && is_object($this->con)) ? mysqli_real_escape_string($this->con, $theValue) : ((trigger_error("[MySQLConverterToo] Fix the mysql_escape_string() call! This code does not work.", E_USER_ERROR)) ? "" : ""));
		
		if( $theType == NULL ) {
			$theType = $this->getValueType($theValue);	
		}

        switch ($theType) {
            case "text":
                $theValue = ($theValue != "") ? "'" . $theValue . "'" : "NULL";
                break;
            case "long":
            case "int":
                $theValue = ($theValue != "") ? intval($theValue) : "NULL";
                break;
            case "double":
                $theValue = ($theValue != "") ? doubleval($theValue) : "NULL";
                break;
            case "date":
                $theValue = ($theValue != "") ? "'" . $theValue . "'" : "NULL";
                break;
            case "defined":
                $theValue = ($theValue != "") ? $theDefinedValue : $theNotDefinedValue;
                break;
        }
        return $theValue;
    }

    public function customQuery($queryString) {
        $this->query = mysqli_query($this->con, $queryString);

        // ensure to reset the results array incase it has been used previously
        $this->result = array();

        if($this->query) {

            $this->numResults = mysqli_num_rows($this->query);

            for($i = 0; $i < $this->numResults; $i++) {
                $r = mysqli_fetch_array($this->query);
                $key = array_keys($r);
                for($x = 0; $x < count($key); $x++) {
                    if(!is_int($key[$x])) {
                        if(mysqli_num_rows($this->query) > 1) {
                            $this->result[$i][$key[$x]] = $r[$key[$x]];
                        } else if(mysqli_num_rows($this->query) < 1) {
                            $this->result = null;
                        } else {
                            $this->result[$key[$x]] = $r[$key[$x]];
                        }
                    }
                }
            }

            return $this;
        } else {
            return false;
        }
    }

    /**
     * Runs the query and returns the MySQL resource that
     *
     * @param String $queryString the SQL query to run
     * @return MySQLResource the default mysql resource
     */
    public function query($queryString, $dieOnError = false) {

        if( Database::$debug ) {
            echo "<pre>" . print_r($queryString) . "</pre>";
        }
        
        // run the query
        $this->query = mysqli_query($this->con, $queryString);
		$this->error = ((is_object($this->con)) ? mysqli_error($this->con) : (($___mysqli_res = mysqli_connect_error()) ? $___mysqli_res : false));
		
		if( $dieOnError && !empty($this->error) ) {
			trigger_error($this->error);
			return $this;
		}
		
		// prepare the result set array
        $this->prepareResult();

        return $this;
    }

    /**
     * Returns the type of the passed var
     * - PHP warns against using gettype(), this is my workaround
     *
     * @param mixed $var
     * @return string
     */
    private function fetchType($var) {
        if (is_bool($var))             $type='boolean';
        else if (is_int($var))         $type='integer';
        else if (is_float($var))     $type='float';
        else if (is_string($var)) {
            $type='string';

            if( strtotime($var) !== false && strtotime($var) != -1 ) {
                $type = 'date';
            }
        }
        else if (is_array($var))     $type='array';
        else if (is_object($var))     $type='object';
        else if (is_null($var))     $type='NULL';
        else $type='unknown type';

        return $type;
    }

    public function getValueType($value) {
        $varType = $this->fetchType($value);
        
        switch($varType) {

            case 'integer':
            case 'float':
                return 'int';

            case 'string':
            case 'boolean':
            case 'array':
            case 'NULL':
                return 'text';

            case 'date':
                return 'date';
        }
    }

    private function prepareResult() {
        // ensure to reset the results array incase it has been used previously
        $this->result = array();

        if( is_object($this->query) ) {
			
            $this->numResults = mysqli_num_rows($this->query);

            for($i = 0; $i < $this->numResults; $i++) {
                $r = mysqli_fetch_array($this->query);
                $keys = array_keys($r);

                for($x = 0; $x < count($keys); $x++) {
                    if(!is_int($keys[$x])) {
                        if( $this->numResults > 1) {
                            $this->result[$i][$keys[$x]] = $r[$keys[$x]];
                        } else if($this->numResults < 1) {
                            $this->result = null;
                        } else {
                            $this->result[$keys[$x]] = $r[$keys[$x]];
                        }
                    }
                }
            }
			
			// free the resource to free space
			((mysqli_free_result($this->query) || (is_object($this->query) && (get_class($this->query) == "mysqli_result"))) ? true : false);

            return true;
        } else {
            return false;
        }
    }

    /**
     * Returns the results of customQuery or querySet as an Array
     *
     * @return Array an array containing the result of the query
     */
    public function getResult() {
        return $this->result;
    }
	
	public function getRow($resultSetArray = NULL, $index = 0) {
		
	   if( $resultSetArray == NULL || func_num_args() == 1 ) {
		   // if the user only specifies one argument, then we expect that argument should be
		   // the index of the item to return from the array
		   if( func_num_args() == 1 ) {
			   $index = $resultSetArray;
		   }
		   
		   $resultSetArray = $this->getResult();
	   }
	   
	   if( $this->getResultCount($resultSetArray) > 1 ) {
		   return $resultSetArray[$index];
	   }
	   
	   return $resultSetArray;
   }
   
   /**
    * Returns the value of the database result array
	*
	* @param Array $data Result Array returned from the Database::getResult() call
	* @param String $key the key for the field column
	*/
   public function getValue($data, $key, $index) {
	   return ( isset($data[$index]) ) ? $data[$index][$key] : $data[$key];  
   }
   
   /**
    * Returns the size of the result array returned from the Database::getResult()
	* call
	*
	* @param Array $data the database array returned from the Database::getResult() call
	*/
   public function getResultCount($data = NULL ) {
	   
	   if( $data == NULL ) {
		  $data = $this->getResult();   
	   }
	   
	   return ( isset($data[0]) ) ? count($data) : 
	   			( count(array_keys($data)) > 0 ? 1 : 0 );
   }
   
   public function getError() {
	   return $this->error;   
   }
   
   public function getInsertId() {
	   return ((is_null($___mysqli_res = mysqli_insert_id($this->con))) ? false : $___mysqli_res);   
   }
}
?>